home *** CD-ROM | disk | FTP | other *** search
- /************************************
- *
- * file: Movie Construction.c
- *
- * This program creates a movie by drawing
- * frames and adding adding them one at a
- * time to the movie.
- *
- * Normally, for a movie, you would use
- * the sequence compression calls so look at that
- * sample, too. This is more appropriate for a slideshow
- * type of movie where there is no continuity from frame to frame
- *
- * by Rich Williams and David van Brink
- * January, 1991
- * updated to 4.04 interfaces
- *
- * 8/91 added making component call to make a preview
- * Updated to MPW/Think 5.0/DSG interfaces 9/91 Chris Thorman
- *
- ***************************************************/
-
- #include "Movies.h"
- #include "QuickTimeComponents.h"
-
- #include <Memory.h>
- #include <Fonts.h>
- #include <Palettes.h>
- #include <OSEvents.h>
- #include <Menus.h>
- #include <Sound.h>
- #include <ToolUtils.h>
- #include <Desk.h>
- #include <Resources.h>
- #include <Errors.h>
- #include <Packages.h>
-
- /************************************
- * Limits and Konstants
- ************************************/
-
- #define kFrameX 120 /* Width & Height */
- #define kFrameY 100
- #define kPixelSize 32
- #define kFrameCnt 25 /* Number of frames to do */
- #define kTimeScale 10 /* frames per second */
-
- /* The fixed point number for 1.00 */
- #define x1Rate (Fixed) 1<<16
-
- /************************************
- * Types and globals
- ************************************/
-
- /* Drawer receives these fields */
- typedef struct
- {
- long frameX,frameY;
- long frameCnt;
- long pixelSize;
- } animationLimits;
-
- /************************************
- * Prototypes
- ************************************/
- static void InitToolbox(void);
- static void MakeFrames(animationLimits *);
- static void ConstructMovie(void);
- void MakePreview(FSSpecPtr theFile, short resRefNum);
-
- void main(void);
-
- /************************************
- *
- * InitToolbox()
- * Start up the tool (and the movie tools!)
- *
- ************************************/
- void InitToolbox()
- {
- OSErr theErr;
-
- MaxApplZone();
- InitGraf(&qd.thePort);
- InitFonts();
- FlushEvents(0xffff,0);
- InitWindows();
- InitMenus();
- InitDialogs(0);
- TEInit();
- InitCursor();
-
- theErr = EnterMovies(); /* Don't forget this. Real men use Alert Dialogs */
- if (theErr) DebugStr((StringPtr) "\pEnterMovies Failed");
- }
-
-
- /************************************
- *
- * Construct Movie()
- * Make a window and call MakeFrames
- *
- ************************************/
- void ConstructMovie()
- {
- WindowPtr w;
- Rect r;
- animationLimits al;
-
- r.left = r.top = 0;
- r.right = kFrameX;
- r.bottom = kFrameY;
-
- OffsetRect(&r,100,100);
- w = NewCWindow(0,&r,(StringPtr)"\pFrames",true,0,(WindowPtr)-1,true,0);
- SetPort(w);
-
- al.frameX = kFrameX;
- al.frameY = kFrameY;
- al.frameCnt = kFrameCnt;
- al.pixelSize = kPixelSize;
-
- MakeFrames(&al); /* write out lots of frames */
-
- CloseWindow(w);
- }
-
-
- /************************************
- *
- * MakeFrames(al)
- * Here is where all the work happens
- *
- ************************************/
- void MakeFrames(al)
-
- animationLimits *al;
-
- {
- short theErr; /* latest error return */
- short resRefNum;
- long i; /* the usual miscellaneous integer */
-
- /* Stuff for creating the file */
- Point dlgPos = {100,100}; /* Position the dialog box */
- SFReply sfr; /* StdFile reply */
- FSSpec mySpec; /* Data structure with filename, etc. */
- short resId;
-
- Movie gMovie; /* Our movie, track and media */
- Track gTrack;
- Media gMedia;
-
- /* Stuff for drawing our frames */
- GWorldPtr myGWorld,oldGWorld;
- GDHandle oldGDevice;
- PixMap *pm,**pmH; /* our offscreen pixmap */
- char c[30]; /* a string, for NumToString */
- Rect r,r2;
-
- /* Stuff for the compressor */
- char **compressedFrameBitsH; /* Buffer for the compressed data */
- long maxCompressedFrameSize; /* Max size of compressed frame */
- long compressedFrameSize; /* Size of current compressed frame */
- CodecType codecType; /* Type of codec to use JPEG etc */
- CompressorComponent codecID; /* Which variation of codecType to use */
- short theDepth; /* Color depth to compress to */
- CodecQ theQuality; /* Quality to compress to */
- ImageDescription **imageDescriptionH; /* Contains info about the sample */
-
-
-
-
-
-
-
- /* Stuff for adding the sample */
- TimeValue sampTime; /* Time sample is added to media */
-
- /******************************
- *
- * Set values for Road Pizza compression
- * You would let the user pick it with a dialog
- *
- *******************************/
- codecID = anyCodec;
- codecType = (CodecType) 'rpza';
- theDepth = 16;
- theQuality = 0x200; /* Quality is 0x100 to 0x300 */
-
-
-
-
- /******************************
- *
- * First we make an empty movie
- *
- *******************************/
- /* Prompt the user for a file name and create it */
- SFPutFile(dlgPos, (StringPtr) "\pMovie file to create:",(StringPtr)"\pTempMovie",nil,&sfr);
- if (!sfr.good)
- return; /* Return if cancel pressed */
-
- ClearMoviesStickyError(); /* Clear any old errors */
-
- theErr = FSMakeFSSpec(sfr.vRefNum, 0, (unsigned char *) sfr.fName, &mySpec);
- if (theErr == fnfErr) theErr = 0;
- if (theErr) DebugStr((StringPtr) "\pFSMakeFSSpec Failed");
-
- theErr = CreateMovieFile( &mySpec, 'TVOD',0,createMovieFileDeleteCurFile,&resRefNum,&gMovie);
- if (theErr) DebugStr((StringPtr) "\pCreateMovieFile Failed");
-
- /* Create the track and media */
- gTrack = NewMovieTrack(gMovie,(long)kFrameX<<16,(long)kFrameY<<16,0);
- if (theErr = GetMoviesError()) DebugStr((StringPtr) "\pNewMovieTrack Failed");
-
- gMedia = NewTrackMedia(gTrack, VideoMediaType, kTimeScale, nil,(OSType) nil);
- if (theErr = GetMoviesError()) DebugStr((StringPtr) "\pNewTrackMedia Failed");
-
- theErr = BeginMediaEdits( gMedia ); /* We do this since we are adding samples to the media */
- if (theErr) DebugStr((StringPtr) "\pBeginMediaEdits Failed");
-
- /******************************
- *
- * Now make a new GWorld to draw the frames to be compressed
- *
- *******************************/
- GetGWorld(&oldGWorld,&oldGDevice); /* save the old port */
-
- r.left = r.top = 0;
- r.right = al->frameX;
- r.bottom = al->frameY;
-
- if (theErr = NewGWorld(&myGWorld,al->pixelSize,&r,nil,nil,0))
- DebugStr((StringPtr) "\pNewGWorld Failed");
- pmH = myGWorld->portPixMap; /* GetGWorldPixMap doesn't always work */
- LockPixels(pmH);
- HLock((Handle)pmH);
- pm = *pmH; /* pm is pointer to pixel-map */
-
- /******************************
- *
- * Now make the buffers and stuff for the compressor
- *
- *******************************/
- imageDescriptionH = (ImageDescription **)NewHandle( 4 ); /* handle for image descriptor */
-
- theErr = GetMaxCompressionSize(&pm,&r,theDepth,theQuality,
- codecType,codecID,&maxCompressedFrameSize); /* How big a buffer do we need? */
-
- if (theErr) DebugStr((StringPtr) "\pGetMaxCompressionSize Failed");
-
- compressedFrameBitsH = NewHandle(maxCompressedFrameSize); /* Make the buffer */
- if (!compressedFrameBitsH) DebugStr((StringPtr) "\pUnable to allocate compression buffer");
-
- HLock(compressedFrameBitsH);
-
- /******************************
- *
- * Don’t Tell the codec manager we are about to start a sequence
- *
- *******************************/
-
-
-
-
-
-
-
-
-
-
-
-
-
- /******************************
- *
- * Now put the movie together one frame at a time
- *
- *******************************/
- for(i = 0; i<al->frameCnt; i++)
- {
- if(Button()) /* A terrific user interface */
- {
- FlushEvents(0xffff,0);
- ExitToShell();
- }
-
- /******************************
- *
- * This is where we draw a single frame of the movie.
- * We're only drawing black and white here, into our big
- * 32-bit offscreen GWorld, because RAM is so cheap.
- *
- *******************************/
-
- SetGWorld(myGWorld,nil);
- EraseRect(&r); /* erase the whole area to white */
-
- MoveTo(20,20);
- NumToString(i+1,(StringPtr)&c);
- DrawString((StringPtr)&c);
-
- r2 = r;
- r2.bottom = (long)r2.bottom * i / (al->frameCnt-1);
- InvertRect(&r2);
-
- /******************************
- *
- * Go back to the old GWorld (the Window)
- * and copybit the frame into it for something to watch
- *
- *******************************/
-
- SetGWorld(oldGWorld,oldGDevice);
- CopyBits((BitMap *) pm,(BitMap *) *(PixMapHandle)(qd.thePort->portBits.baseAddr),&r,&r,0,0);
-
- /******************************
- *
- * Compress the Frame
- *
- *******************************/
-
- theErr = CompressImage(pmH,
- &r,
- theQuality,
- codecType,
- imageDescriptionH,
- *compressedFrameBitsH);
-
-
-
- compressedFrameSize = (**imageDescriptionH).dataSize;
-
- if (theErr) DebugStr((StringPtr) "\pCompressImage Failed");
-
- /******************************
- *
- * And add it to the media
- *
- *******************************/
-
- theErr = AddMediaSample(gMedia,
- compressedFrameBitsH,
- 0L,
- compressedFrameSize,
- (TimeValue)1,
- (SampleDescriptionHandle) imageDescriptionH,
- 1L,
- 0,
- &sampTime);
-
- if (theErr) DebugStr((StringPtr) "\pAddMediaSample Failed");
-
- /* And loop back for the next frame */
- }
-
- /******************************
- *
- * Now close up the movie
- * and throw out our buffers and stuff
- *
- *******************************/
-
-
-
- theErr = EndMediaEdits( gMedia ); /* We're done adding samples */
- if (theErr) DebugStr((StringPtr) "\pEndMediaEdits Failed");
-
- theErr = InsertMediaIntoTrack(gTrack,0L,0L,GetMediaDuration(gMedia),x1Rate);
- if (theErr) DebugStr((StringPtr) "\pInsertMediaIntoTrack Failed");
-
- resId = 1;
- theErr = AddMovieResource( gMovie, resRefNum, &resId, (char *)sfr.fName );
- if (theErr) DebugStr((StringPtr) "\pAddMovieResource Failed");
-
- UpdateResFile(resRefNum);
-
- MakePreview(&mySpec,resRefNum); /* Add a preview to the file */
-
- theErr = CloseMovieFile( resRefNum );
- if (theErr) DebugStr((StringPtr) "\pCloseMovieFile Failed");
-
- DisposeMovie(gMovie); /* We don't need the movie anymore */
- DisposHandle(compressedFrameBitsH);
- DisposHandle((Handle)imageDescriptionH);
- DisposeGWorld(myGWorld);
-
- }
-
- /******************************
- *
- * MakePreview
- * makes a preview for the movie
- *
- *******************************/
- void MakePreview(FSSpecPtr theFile, short resRefNum)
-
- {
- ComponentInstance thePreviewMaker;
- Component thePreviewComponent;
- ComponentDescription tDesc;
- OSErr theErr;
-
- /* Find a preview component */
- tDesc.componentType = 'prvt';
- tDesc.componentSubType = 'MooV';
- tDesc.componentManufacturer = 0;
- tDesc.componentFlags = 0;
- tDesc.componentFlagsMask = 0;
- thePreviewComponent = FindNextComponent( (Component) 0,&tDesc);
-
- /* an instance of the component */
- thePreviewMaker = OpenComponent(thePreviewComponent);
-
- if(thePreviewMaker == nil) /* Did it fail? */
- return;
-
- /* Now put the preview into the file */
- theErr = PreviewerCreatePreviewForResRefNum(thePreviewMaker, resRefNum, theFile, true, nil, nil);
-
- CloseComponent(thePreviewMaker); /* Throw out the component */
-
-
- }
-
- /******************************
- *
- * The main routine
- * It doesn't look like much but I'm proud of it
- *
- *******************************/
- void main()
- {
- InitToolbox(); /* Start up the tools */
- ConstructMovie(); /* Make the movie */
- }
-
-